package cn.iocoder.yudao.module.product.controller.admin.spu;

import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.product.enums.spu.ProductTypeEnum;
import cn.iocoder.yudao.module.product.service.sku.IESimSkuService;
import cn.iocoder.yudao.module.product.service.sku.IGiftCardSkuService;
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
import cn.iocoder.yudao.module.product.util.ProductUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 商品 SKU")
@RestController
@RequestMapping("/product/sku")
@Validated
@Slf4j
public class ProductSkuController {

    @Resource
    private ProductSpuService productSpuService;
    @Resource
    private ProductSkuService productSkuService;
    @Resource
    private IGiftCardSkuService giftCardSkuService;
    @Resource
    private IESimSkuService simSkuService;

    @PostMapping("/create")
    @Operation(summary = "创建商品 SKU")
    @PreAuthorize("@ss.hasPermission('product:spu:create')")
    public CommonResult<Long> createProductSku(@Valid @RequestBody ProductSkuSaveReqV2VO createReqVO) {
        checkCreateOrUpdateSku(createReqVO, true);
        final Long skuId = productSkuService.createSku(createReqVO);
        productSpuService.initSpuFromSkus(createReqVO.getSpuId());
        return success(skuId);
    }

    @PutMapping("/update")
    @Operation(summary = "更新商品 SKU")
    @PreAuthorize("@ss.hasPermission('product:spu:update')")
    public CommonResult<Boolean> updateSku(@Valid @RequestBody ProductSkuSaveReqV2VO updateReqVO) {
        ProductUtil.checkFieldNullable(updateReqVO.getId(), updateReqVO, "id");
        checkCreateOrUpdateSku(updateReqVO, false);
        productSkuService.updateSkuWithNullById(updateReqVO.getId(), updateReqVO);
        productSpuService.initSpuFromSkus(updateReqVO.getSpuId());
        return success(true);
    }

    @PutMapping("/update-status")
    @Operation(summary = "更新商品 SKU Status")
    @PreAuthorize("@ss.hasPermission('product:spu:update')")
    public CommonResult<Boolean> updateStatus(@Valid @RequestBody ProductSkuUpdateStatusReqVO updateReqVO) {
        final ProductSkuDO productSkuDO = productSkuService.updateSkuStatus(updateReqVO);
        productSpuService.initSpuFromSkus(productSkuDO.getSpuId());
        return success(true);
    }

    @GetMapping("/list")
    @Operation(summary = "获得商品 SKU 详情列表")
    @Parameter(name = "spuId", description = "spu 编号", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('product:spu:query')")
    public CommonResult<List<ProductSkuRespVO>> getSpuList(@RequestParam("spuId") Long spuId) {
        final List<ProductSkuDO> skuDOList = productSkuService.getSkuListBySpuId(spuId, null);
        final List<ProductSkuRespVO> voList = BeanUtils.toBean(skuDOList, ProductSkuRespVO.class);
        return success(voList);
    }

    @GetMapping("/get-detail")
    @Operation(summary = "获得商品 SKU 明细")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('product:spu:query')")
    public CommonResult<ProductSkuRespVO> getSkuDetail(@RequestParam("id") Long id) {
        final ProductSkuDO skuDO = productSkuService.getSku(id);
        final ProductSkuRespVO skuVO = BeanUtils.toBean(skuDO, ProductSkuRespVO.class);
        return success(skuVO);
    }

    private void checkCreateOrUpdateSku(ProductSkuSaveReqV2VO createReqVO, boolean create) {
        // 查询spu
        final Long spuId = createReqVO.getSpuId();
        final ProductSpuDO spu = productSpuService.getSpu(spuId);
        if (spu == null) {
            log.warn("spu不存在, spuId = {}", spuId);
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.SPU_NOT_EXISTS);
        }

        final ProductTypeEnum productTypeEnum = ProductTypeEnum.fromValue(spu.getProductType());
        switch (productTypeEnum) {
            case GIFT_CARD:
                giftCardSkuService.checkCreateOrUpdateSku(createReqVO, spu, create);
                break;
            case ESIM_CARD:
                simSkuService.checkCreateOrUpdateSku(createReqVO, spu, create);
                break;
            default:
                throw ServiceExceptionUtil.exception(ErrorCodeConstants.SPU_FIELD_DEFAULT_ERROR, String.format("未知的productTypeEnum = %s", productTypeEnum));
        }
    }

    @RequestMapping(path = "/delete", method = {RequestMethod.DELETE, RequestMethod.POST})
    @Operation(summary = "删除 SKU")
    @Parameter(name = "skuId", description = "sku 编号", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('product:spu:delete')")
    public CommonResult<Void> deleteSku(@RequestParam("skuId") Long skuId) {
        productSkuService.deleteSku(skuId);
        return success(null);
    }

}
